#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <iostream>
#include <errno.h>
using namespace std;

// libcap-devel needed
// g++ getrlimit.cpp -lcap

int main(int argc, char *argv[])
{
	int ret = prctl(PR_CAPBSET_READ,CAP_SYS_RESOURCE,0,0);
	if (ret == 1)
	{
		cout<<"CAP_SYS_RESOURCE enabled"<<endl;
	}
	else
		cout<<"CAP_SYS_RESOURCE disabled"<<endl;

	struct rlimit rt,rt_new;
	ret = getrlimit(RLIMIT_NOFILE,&rt);
	if (ret != 0)
	{
		cout<<"getrlimit error"<<endl;
		return 0;
	}
	cout<<"old soft limit:"<<rt.rlim_cur<<"\told hard limit:"<<rt.rlim_max<<endl;

	rt.rlim_cur = rt.rlim_max = 40960000;
	ret = setrlimit(RLIMIT_NOFILE,&rt);
	if (ret != 0)
	{
		cout<<"setrlimt error:"<<errno<<endl;
		cap_t caps = cap_init();
		cap_value_t caplist[2] = {CAP_SYS_RESOURCE,CAP_SETPCAP};
		unsigned int num_caps = 2;
		cap_set_flag(caps,CAP_EFFECTIVE,num_caps,caplist,CAP_SET);
		cap_set_flag(caps,CAP_INHERITABLE,num_caps,caplist,CAP_SET);
		cap_set_flag(caps,CAP_PERMITTED,num_caps,caplist,CAP_SET);
		if (cap_set_proc(caps))
		{
			cout<<"cap_set_proc failed"<<endl;
			return 0;
		}
		ret = setrlimit(RLIMIT_NOFILE,&rt);
		if (ret != 0)
		{
			cout<<"setrlimit error:"<<errno<<endl;
			return 0;
		}
	}

	ret = getrlimit(RLIMIT_NOFILE,&rt_new);
	if (ret != 0)
	{
		cout<<"getrlimit error:"<<errno<<endl;
		return 0;
	}
	cout<<"new soft limit:"<<rt_new.rlim_cur<<"\tnew hard limit:"<<rt_new.rlim_max<<endl;
	return 0;
}